home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998…tember: Reference Library / Dev.CD Sep 98 RL1.toast / Technical Documentation / develop / develop Issue 23 / develop Issue 23 code / QuickTime Music / QTMADevelop95.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-03  |  16.5 KB  |  738 lines  |  [TEXT/CWIE]

  1.      
  2. /*--------------------------
  3.     Inclusions
  4. --------------------------*/
  5.  
  6. #include <QuickDraw.h>
  7. #include <Windows.h>
  8. #include <StandardFile.h>
  9. #include <OSUtils.h>
  10. #include <Script.h>
  11. #include <QuickTimeComponents.h>
  12.  
  13. #include "BigEasy2.h"
  14.  
  15. /*--------------------------
  16.     Limits and Konstants
  17. --------------------------*/
  18. enum
  19.     {
  20.     mOpen = 100,
  21.     mClose
  22.     };
  23.  
  24. typedef struct
  25.     {
  26.     WindowPtr w;
  27.     } Globals;
  28.  
  29. static Globals g;
  30.  
  31.  
  32. /*--------------------------
  33.     Prototypes
  34. --------------------------*/
  35. static void GoAwayDoc(short n);
  36. static void LetsQuit(short n,short menuItem,short menuRef);
  37. static void OpenWindow(short n,short menuItem,short menuRef);
  38. static void InitVars(void);
  39.  
  40. static void SDrawDoc(short n);
  41. static void SClickDoc(short n,Point p,short mods);
  42. static void SKeyDoc(short n,short key,short code,short mods);
  43. static void SIdleDoc(short n, Boolean front);
  44.  
  45. void ActivateDoc(short n);
  46. void DeactivateDoc(short n);
  47.  
  48.  
  49. /*--------------------------
  50.     Computer Programs
  51. --------------------------*/
  52.  
  53.  
  54.  
  55.  
  56. void PlaySomeNotes(short a,short b,short c);
  57. void PickThenPlaySomeNotes(short xx1,short xx2,short xx3);
  58. void PlaySomeBentNotes(short xx1,short xx2,short xx3);
  59. unsigned long *BuildTuneHeader(long *longCount);
  60. Handle BuildTuneSequence(long *duration);
  61. void BuildSequenceAndPlay(short xx1,short xx2,short xx3);
  62. void BuildMusicMovie(short xx1,short xx2,short xx3);
  63. void UseMIDIInput(short xx1,short xx2,short xx3);
  64.  
  65.  
  66. void PlaySomeNotes(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */
  67.     {
  68.     NoteAllocator na;
  69.     NoteChannel nc;
  70.     NoteRequest nr;
  71.     ComponentResult thisError;
  72.     long t,i;
  73.  
  74.     na = 0;
  75.     nc = 0;
  76.  
  77.     /*
  78.      * Open up the Note Allocator
  79.      */
  80.     na = OpenDefaultComponent('nota',0);
  81.     if(!na)
  82.         goto goHome;
  83.  
  84.     /*
  85.      * Fill out a Note Request using NAStuffToneDescription
  86.      * to help, and allocate a Note Channel
  87.      */
  88.     nr.polyphony = 2;        /* simultaneous tones */
  89.     nr.typicalPolyphony = 0x00010000;
  90.     thisError = NAStuffToneDescription(na,1,&nr.tone);    /* 1 is Piano */
  91.  
  92.     thisError = NANewNoteChannel(na,&nr,&nc);
  93.     if(thisError || !nc)
  94.         goto goHome;
  95.  
  96.     /*
  97.      * If we've gotten this far, then things are ok
  98.      * to play some musical notes. Lovely.
  99.      */
  100.     NAPlayNote(na,nc,60,80);    /* middle C at velocity 80 */
  101.     Delay(40,&t);            /* delay 2/3 of a second */
  102.     NAPlayNote(na,nc,60,0);    /* middle C at velocity 0: end note */
  103.     Delay(40,&t);            /* delay 2/3 of a second */
  104.  
  105.     /*
  106.      * Obligatory do-loop of rising tones
  107.      */
  108.     for(i = 60; i <= 84; i++)
  109.         {
  110.         NAPlayNote(na,nc,i,80);    /* pitch i at velocity 80 */
  111.         NAPlayNote(na,nc,i+7,80);    /* pitch i+7 (musical fifth) at velocity 80 */
  112.         Delay(10,&t);            /* delay 1/6 of a second */
  113.         NAPlayNote(na,nc,i,0);    /* pitch i at velocity 0: end note */
  114.         NAPlayNote(na,nc,i+7,0);    /* pitch i+7 at velocity 0: end note */
  115.         }
  116. goHome:
  117.     if(nc)
  118.         NADisposeNoteChannel(na,nc);
  119.     if(na)
  120.         CloseComponent(na);
  121.     }
  122.  
  123. void PlayShepardMelody(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */;
  124. void PlayShepardMelody(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */
  125.     {
  126.     NoteAllocator na;
  127.     NoteChannel nc;
  128.     NoteRequest nr;
  129.     ComponentResult thisError;
  130.     unsigned long i,j,v;
  131.     long t;
  132.  
  133.     na = 0;
  134.     nc = 0;
  135.  
  136.     /*
  137.      * Open up the Note Allocator
  138.      */
  139.     na = OpenDefaultComponent('nota',0);
  140.     if(!na)
  141.         goto goHome;
  142.  
  143.     /*
  144.      * Fill out a Note Request using NAStuffToneDescription
  145.      * to help, and allocate a Note Channel
  146.      */
  147.     nr.polyphony = 3;        /* simultaneous tones */
  148.     nr.typicalPolyphony = 0x00010000;
  149.     thisError = NAStuffToneDescription(na,1,&nr.tone);    /* 1 is Piano */
  150.  
  151.     thisError = NANewNoteChannel(na,&nr,&nc);
  152.     if(thisError || !nc)
  153.         goto goHome;
  154.  
  155.     /*
  156.      * play Roger Shepard's melody
  157.      */
  158.     i = 0;
  159.     while(!Button())
  160.         {
  161.         for(j = i % 13; j < 128; j+=13)
  162.             {
  163.             v = j<64 ? j * 2 : (127 - j) * 2;
  164.             NAPlayNote(na,nc,j,v);
  165.             }
  166.         Delay(13,&t);
  167.         for(j = i % 13; j < 128; j+=13)
  168.             NAPlayNote(na,nc,j,0);
  169.         i++;
  170.         }
  171. goHome:
  172.     if(nc)
  173.         NADisposeNoteChannel(na,nc);
  174.     if(na)
  175.         CloseComponent(na);
  176.     }
  177.  
  178.  
  179.  
  180. void PickThenPlaySomeNotes(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */
  181.     {
  182.     NoteAllocator na;
  183.     NoteChannel nc;
  184.     NoteRequest nr;
  185.     ComponentResult thisError;
  186.     long t,i;
  187.  
  188.     na = 0;
  189.     nc = 0;
  190.  
  191.     /*
  192.      * Open up the Note Allocator
  193.      */
  194.     na = OpenDefaultComponent('nota',0);
  195.     if(!na)
  196.         goto goHome;
  197.  
  198.     /*
  199.      * Fill out a Note Request using NAStuffToneDescription
  200.      * to help, and allocate a Note Channel
  201.      */
  202.     nr.polyphony = 2;        /* simultaneous tones */
  203.     nr.typicalPolyphony = 0x00010000;
  204.     thisError = NAStuffToneDescription(na,1,&nr.tone);    /* 1 is Piano */
  205.  
  206.     thisError = NAPickInstrument(na,nil,"\pPick An Instrument:",&nr.tone, 0,0,0,0);
  207.     if(thisError)
  208.         goto goHome;
  209.  
  210.     thisError = NANewNoteChannel(na,&nr,&nc);
  211.     if(thisError || !nc)
  212.         goto goHome;
  213.  
  214.     /*
  215.      * If we've gotten this far, then things are ok
  216.      * to play some musical notes. Lovely.
  217.      */
  218.     NAPlayNote(na,nc,60,80);    /* middle C at velocity 80 */
  219.     Delay(40,&t);            /* delay 2/3 of a second */
  220.     NAPlayNote(na,nc,60,0);    /* middle C at velocity 0: end note */
  221.     Delay(40,&t);            /* delay 2/3 of a second */
  222.  
  223.     /*
  224.      * Obligatory do-loop of rising tones
  225.      */
  226.     for(i = 60; i <= 84; i++)
  227.         {
  228.         NAPlayNote(na,nc,i,80);    /* pitch i at velocity 80 */
  229.         NAPlayNote(na,nc,i+7,80);    /* pitch i+7 (musical fifth) at velocity 80 */
  230.         Delay(10,&t);            /* delay 1/6 of a second */
  231.         NAPlayNote(na,nc,i,0);    /* pitch i at velocity 0: end note */
  232.         NAPlayNote(na,nc,i+7,0);    /* pitch i+7 at velocity 0: end note */
  233.         }
  234. goHome:
  235.     if(nc)
  236.         NADisposeNoteChannel(na,nc);
  237.     if(na)
  238.         CloseComponent(na);
  239.     }
  240.  
  241.  
  242.  
  243. void PlaySomeBentNotes(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */
  244.     {
  245.     NoteAllocator na;
  246.     NoteChannel nc;
  247.     NoteRequest nr;
  248.     ComponentResult thisError;
  249.     long t,i;
  250.  
  251.     na = 0;
  252.     nc = 0;
  253.  
  254.     /*
  255.      * Open up the Note Allocator
  256.      */
  257.     na = OpenDefaultComponent('nota',0);
  258.     if(!na)
  259.         goto goHome;
  260.  
  261.     /*
  262.      * Fill out a Note Request using NAStuffToneDescription
  263.      * to help, and allocate a Note Channel
  264.      */
  265.     nr.polyphony = 2;        /* simultaneous tones */
  266.     nr.typicalPolyphony = 0x00010000;
  267.     thisError = NAStuffToneDescription(na,17,&nr.tone);    /* 17 is an organ tone */
  268.  
  269.     thisError = NANewNoteChannel(na,&nr,&nc);
  270.     if(thisError || !nc)
  271.         goto goHome;
  272.  
  273.     Delay(30,&t);
  274.  
  275.     /*
  276.      * If we've gotten this far, then things are ok
  277.      * to play some musical notes. Lovely.
  278.      */
  279.     NAPlayNote(na,nc,60,80);    /* middle C at velocity 80 */
  280.     NAPlayNote(na,nc,67,60);    /* g at velocity 60 */
  281.     Delay(30,&t);
  282.  
  283.     /*
  284.      * Loop through differing pitch bendings
  285.      */
  286.     for(i = 0; i <= 768; i+= 10)        /* bend 3 semitones */
  287.         {
  288.         NASetController(na,nc,kControllerPitchBend,i);
  289.         Delay(1,&t);
  290.         }
  291.     Delay(30,&t);
  292.     for(i = 768; i >= 0; i-= 10)        /* bend back to normal*/
  293.         {
  294.         NASetController(na,nc,kControllerPitchBend,i);
  295.         Delay(1,&t);
  296.         }
  297.     Delay(30,&t);
  298.  
  299.     NAPlayNote(na,nc,60,0);    /* middle C off */
  300.     NAPlayNote(na,nc,67,0);    /* G off */
  301.  
  302. goHome:
  303.     if(nc)
  304.         NADisposeNoteChannel(na,nc);
  305.     if(na)
  306.         CloseComponent(na);
  307.     }
  308.  
  309.  
  310. #define kNoteRequestHeaderEventLength (sizeof(NoteRequest)/sizeof(long) + 2) /* longwords */
  311. unsigned long *BuildTuneHeader(long *longCount)
  312.     {
  313.     unsigned long *header;
  314.     unsigned long *w,*w2;
  315.     NoteRequest *nr;
  316.     NoteAllocator na;    /* just for the NAStuffToneDescription call */
  317.     ComponentResult thisError;
  318.  
  319.     header = 0;
  320.     na = 0;
  321.  
  322.     /*
  323.      * Open up the Note Allocator
  324.      */
  325.     na = OpenDefaultComponent('nota',0);
  326.     if(!na)
  327.         goto goHome;
  328.  
  329.     /*
  330.      * Allocate space for the tune header,
  331.      * rather inflexibly.
  332.      */
  333.     header = (unsigned long *)
  334.             NewPtrClear((2 * kNoteRequestHeaderEventLength + 1) * sizeof(long));
  335.     if(!header)
  336.         goto goHome;
  337.  
  338.     w = header;
  339.  
  340.     /*
  341.      * Stuff request for piano polyphony 4
  342.      */
  343.     w2 = w + kNoteRequestHeaderEventLength - 1; /* last longword of general event */
  344.     _StuffGeneralEvent(*w,*w2, 1, kGeneralEventNoteRequest, kNoteRequestHeaderEventLength);
  345.     nr = (NoteRequest *)(w + 1);
  346.     nr->polyphony = 4;        /* simultaneous tones */
  347.     nr->typicalPolyphony = 0x00010000;
  348.     thisError = NAStuffToneDescription(na,1,&nr->tone);    /* 1 is Piano */
  349.     w += kNoteRequestHeaderEventLength;
  350.  
  351.     /*
  352.      * Stuff request for violin polyphony 3
  353.      */
  354.     w2 = w + kNoteRequestHeaderEventLength - 1; /* last longword of general event */
  355.     _StuffGeneralEvent(*w,*w2, 2, kGeneralEventNoteRequest, kNoteRequestHeaderEventLength);
  356.     nr = (NoteRequest *)(w + 1);
  357.     nr->polyphony = 3;        /* simultaneous tones */
  358.     nr->typicalPolyphony = 0x00010000;
  359.     thisError = NAStuffToneDescription(na,41,&nr->tone);    /* ???!!! what is violin? */
  360.     w += kNoteRequestHeaderEventLength;
  361.  
  362.     *w++ = 0x60000000;        /* end of sequence marker */
  363.  
  364.  
  365. goHome:
  366.     if(na)
  367.         CloseComponent(na);
  368.  
  369.     if(longCount)
  370.         *longCount = 2 * kNoteRequestHeaderEventLength;
  371.  
  372.     return header;
  373.     }
  374.  
  375. Handle BuildTuneSequence(long *duration)
  376.     {
  377.     unsigned long *sequence;
  378.     unsigned long *w;
  379.     Handle h;
  380.  
  381.     /*
  382.      * Allocate space for the tune sequence,
  383.      * rather inflexibly.
  384.      */
  385. #define kNoteDuration 240 /* in 600ths of a second */
  386. #define kRestDuration 300 /* in 600ths - tempo will be 120bpm */
  387.  
  388.     h = NewHandleClear(22 * sizeof(long));
  389.     if(!h)
  390.         goto goHome;
  391.     HLock(h);
  392.     sequence = (unsigned long *) *h;
  393.  
  394.     w = sequence;
  395.  
  396.     _StuffNoteEvent(*w++,1,60,100,kNoteDuration);    /* piano C */
  397.     _StuffRestEvent(*w++,kRestDuration);
  398.     _StuffNoteEvent(*w++,2,60,100,kNoteDuration);    /* violin C */
  399.     _StuffRestEvent(*w++,kRestDuration);
  400.  
  401.     _StuffNoteEvent(*w++,1,63,100,kNoteDuration);    /* piano */
  402.     _StuffRestEvent(*w++,kRestDuration);
  403.     _StuffNoteEvent(*w++,2,64,100,kNoteDuration);    /* violin */
  404.     _StuffRestEvent(*w++,kRestDuration);
  405.  
  406.     /*
  407.      * make the 5th and 6th notes much softer, just for fun
  408.      */
  409.     _StuffNoteEvent(*w++,1,67,60,kNoteDuration);    /* piano */
  410.     _StuffRestEvent(*w++,kRestDuration);
  411.     _StuffNoteEvent(*w++,2,66,60,kNoteDuration);    /* violin */
  412.     _StuffRestEvent(*w++,kRestDuration);
  413.  
  414.     _StuffNoteEvent(*w++,1,72,100,kNoteDuration);    /* piano */
  415.     _StuffRestEvent(*w++,kRestDuration);
  416.     _StuffNoteEvent(*w++,2,73,100,kNoteDuration);    /* violin */
  417.     _StuffRestEvent(*w++,kRestDuration);
  418.  
  419.     _StuffNoteEvent(*w++,1,60,100,kNoteDuration);    /* piano */
  420.     _StuffNoteEvent(*w++,1,67,100,kNoteDuration);    /* piano */
  421.     _StuffNoteEvent(*w++,2,63,100,kNoteDuration);    /* violin */
  422.     _StuffNoteEvent(*w++,2,72,100,kNoteDuration);    /* violin */
  423.     _StuffRestEvent(*w++,kRestDuration);
  424.  
  425.     *w++ = 0x60000000;    /* end marker */
  426.  
  427. goHome:
  428.     if(duration)
  429.         *duration = 9 * kRestDuration;
  430.     return h;
  431.     }
  432.  
  433.  
  434. void BuildSequenceAndPlay(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */
  435.     {
  436.     Handle sequenceH;
  437.     unsigned long *header;
  438.     unsigned long *sequence;
  439.     TunePlayer tp;
  440.     TuneStatus ts;
  441.     ComponentResult thisError;
  442.  
  443.     tp = 0;
  444.  
  445.     header = BuildTuneHeader(nil);
  446.     sequenceH = BuildTuneSequence(nil);
  447.  
  448.     if(!sequenceH || !header)
  449.         goto goHome;
  450.  
  451.     sequence = (unsigned long *)*sequenceH;
  452.  
  453.     tp = OpenDefaultComponent(kTunePlayerType,0);
  454.     if(!tp)
  455.         goto goHome;
  456.  
  457.     thisError = TuneSetHeader(tp,header);
  458.  
  459.         {
  460.         long t;
  461.         Delay(10,&t);
  462.         }
  463.  
  464.     thisError = TuneQueue(tp,sequence,0x00010000,0,0x7FFFFFFF,0,0,0);
  465.  
  466.     /*
  467.      * wait until the sequence finishes playing,
  468.      * or the user clicks the mouse.
  469.      */
  470. spin:
  471.     thisError = TuneGetStatus(tp,&ts);
  472.     if(ts.queueTime && !Button())
  473.         goto spin;    /* I like to use gotos primarily to shock the children. */
  474.  
  475. goHome:
  476.     if(tp)
  477.         CloseComponent(tp);
  478.     if(header)
  479.         DisposePtr((Ptr)header);
  480.     if(sequenceH)
  481.         DisposeHandle(sequenceH);
  482.     }
  483.  
  484.  
  485. typedef struct
  486.     {
  487.     NoteAllocator na;
  488.     NoteChannel nc;
  489.     } MIDIInputExample;
  490.  
  491. pascal ComponentResult AReadHook(MusicMIDIPacket *mp, long refCon);
  492. pascal ComponentResult AReadHook(MusicMIDIPacket *mp, long refCon)
  493.     {
  494.     MIDIInputExample *mie;
  495.     Boolean major;
  496.     short status,pitch,vel;
  497.  
  498.     mie = (MIDIInputExample *)refCon;
  499.  
  500. //    if(mp->reserved == kMusicPacketPortLost)        /* port gone? make channel quiet */
  501. //        NASetNoteChannelVolume(mie->na,mie->nc,0);
  502. //    else if(mp->reserved == kMusicPacketPortFound)    /* port back? raise volume */
  503. //        NASetNoteChannelVolume(mie->na,mie->nc,0x00010000);
  504. //    else 
  505.     if(mp->length == 3)
  506.         {
  507.         status = mp->data[0] & 0xF0;
  508.         pitch = mp->data[1];
  509.         vel = mp->data[2];
  510.         switch(status)
  511.             {
  512.             case 0x80:
  513.                 vel = 0;
  514.     /* falls into case 0x90. Almost as fun as a goto, hmm, mom? */
  515.             case 0x90:
  516.                 major = pitch % 5 == 0;
  517.                 NAPlayNote(mie->na,mie->nc,pitch,vel);
  518.                 NAPlayNote(mie->na,mie->nc,pitch+3+major,vel);
  519.                 NAPlayNote(mie->na,mie->nc,pitch+7,vel);
  520.                 break;
  521.             }
  522.         }
  523.     return noErr;
  524.     }
  525.  
  526.  
  527. void UseMIDIInput(short xx1,short xx2,short xx3)
  528.     {
  529.     ComponentResult result;
  530.     MIDIInputExample mie;
  531.     NoteRequest nr;
  532.     MusicMIDIReadHookUPP readHookUPP = nil;
  533.  
  534.     mie.na = OpenDefaultComponent('nota',0);
  535.     if(!mie.na)
  536.         goto goHome;
  537.  
  538.     nr.polyphony = 2;
  539.     nr.typicalPolyphony = 0x00010000;
  540.     result = NAStuffToneDescription(mie.na,1,&nr.tone);        /* piano */
  541.     result = NANewNoteChannel(mie.na,&nr,&mie.nc);
  542.     
  543.     readHookUPP = NewMusicMIDIReadHookProc(AReadHook);
  544.     result = NAUseDefaultMIDIInput(mie.na,readHookUPP,(long)&mie,0);
  545.     while(!Button());
  546.     result = NALoseDefaultMIDIInput(mie.na);
  547.  
  548. goHome:
  549.     if(readHookUPP)
  550.         DisposeRoutineDescriptor(readHookUPP);
  551.     if(mie.na)
  552.         CloseComponent(mie.na);        /* disposes notechannel too */
  553.     }
  554.  
  555.  
  556.  
  557.  
  558. void BuildMusicMovie(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */
  559.     {
  560.     ComponentResult result;
  561.     StandardFileReply reply;
  562.     short resRefNum;
  563.     Movie mo;
  564.     Track tr;
  565.     Media me;
  566.     MusicDescription *md,**mdH;
  567.     long duration,headerLength;
  568.     unsigned long *w,*header;
  569.     Handle tuneH;
  570.  
  571.     // • prompt user for new file name
  572.  
  573.     StandardPutFile ("\pMusic movie file name:", "\pMovie File", &reply );
  574.     if(!reply.sfGood)
  575.         goto goHome;
  576.  
  577.     // • create the movie, and track, and media
  578.  
  579.     result = CreateMovieFile(&reply.sfFile,'TVOD',smCurrentScript,createMovieFileDeleteCurFile,&resRefNum,&mo);
  580.     tr = NewMovieTrack(mo,0,0,256);
  581.     me = NewTrackMedia(tr,MusicMediaType, 600, nil, 0 );
  582.  
  583.     // • create a music sample description
  584.  
  585.     header = BuildTuneHeader(&headerLength);
  586.  
  587.     mdH = (MusicDescription **)NewHandleClear(sizeof(MusicDescription) - 4
  588.             + headerLength*sizeof(long)
  589.             + 4);                                                    /* end marker */
  590.     if(!mdH)
  591.         goto goHome;
  592.  
  593.     md = *mdH;
  594.     md->descSize = GetHandleSize((Handle)mdH);
  595.     md->dataFormat = 'musi';
  596.     w = md->headerData;
  597.     BlockMove(header,w,headerLength * sizeof(long));
  598.     w += headerLength;
  599.     *w = 0x60000000;
  600.  
  601.     DisposePtr((Ptr)header);
  602.  
  603.     // • Get a tune, and add it to the media, then finish up.
  604.  
  605.     tuneH = BuildTuneSequence(&duration);
  606.  
  607.     result = BeginMediaEdits(me);
  608.  
  609.     result = AddMediaSample(me,tuneH,0,
  610.             GetHandleSize(tuneH),
  611.             duration,(SampleDescriptionHandle)mdH,
  612.             1,0,nil);
  613.  
  614.     result = EndMediaEdits(me);
  615.     result = InsertMediaIntoTrack(tr,0,0,duration,(1L<<16));
  616.  
  617.     result = OpenMovieFile(&reply.sfFile, &resRefNum,
  618.             fsRdWrPerm);
  619.     result = AddMovieResource( mo,resRefNum, 0, 0);
  620.     result = CloseMovieFile(resRefNum);
  621.  
  622.     DisposeMovie(mo);
  623. goHome:;
  624.     }
  625.  
  626.  
  627. void GoAwayDoc(short n)
  628. /*
  629.  * Close that window...
  630.  */
  631.     {
  632.     UninstallWindow(n);
  633.     }
  634.  
  635. void ActivateDoc(short n)
  636.     {
  637. #pragma unused (n)
  638.      SetMenuItem(mClose,1,0,0,nil);                /* enable "Close" menu item        */
  639.     SetMenuItem(mOpen,-1,0,0,nil);                /* disable "Open" menu item        */
  640.     }
  641.  
  642. void DeactivateDoc(short n)
  643.     {
  644. #pragma unused (n)
  645.     SetMenuItem(mClose,-1,0,0,nil);                /* disable "Close" menu item    */
  646.     SetMenuItem(mOpen,1,0,0,nil);                /* enable "Open" menu item        */
  647.     }
  648.  
  649. void LetsQuit(short n,short menuItem,short menuRef)
  650.     {
  651. #pragma unused (n,menuItem,menuRef)
  652.     gQuitApp++;
  653.     }
  654.  
  655. #define kWindowWidth 200
  656. #define kWindowHeight 100
  657.  
  658. void OpenWindow(short n,short menuItem,short menuRef)
  659.     {
  660. #pragma unused (n,menuItem,menuRef)
  661.     Rect r;
  662.  
  663.     SetRect(&r,0,0,kWindowWidth,kWindowHeight);
  664.     OffsetRect(&r,20,40);
  665.  
  666.     g.w = InstallWindow(1,"\p",&r,0,wCopyDraw,
  667.                                 SDrawDoc,SClickDoc,SKeyDoc,nil,
  668.                                 ActivateDoc,DeactivateDoc,SIdleDoc);
  669.     }
  670.  
  671. static void SDrawDoc(short n)
  672.     {
  673.     EraseRect(&gBigRect);
  674.     MoveTo(10,50);
  675.     DrawString("\pExamples of QuickTime Music Architecture");
  676.     MoveTo(10,65);
  677.     DrawString("\pDavid Van Brink, 1995");
  678.     MoveTo(10,80);
  679.     DrawString("\p©Apple Computer");
  680.     }
  681.  
  682. static void SClickDoc(short n,Point p,short mods)
  683.     {
  684.     }
  685.  
  686. static void SKeyDoc(short n,short key,short code,short mods)
  687.     {
  688.     }
  689.  
  690. static void SIdleDoc(short n, Boolean front)
  691.     {
  692.     }
  693.  
  694.  
  695.  
  696.  
  697.  
  698. void InitVars()
  699. /*
  700.  * Called once at startup: yes, it
  701.  * inits the vars.
  702.  */
  703.     {
  704.     EnterMovies();
  705.     }
  706.  
  707.  
  708.  
  709. void Bootstrap()
  710.     {
  711.     InitVars();
  712.  
  713. /*** File Menu ***/
  714.     InstallMenu("\pFile",nil,0);
  715.     InstallMenuItem("\pQuit/Q",LetsQuit,0);
  716.     InstallMenuItem("\p(-",nil,0);
  717.     InstallMenuItem("\pPlay Some Notes/1",PlaySomeNotes,0);
  718.     InstallMenuItem("\pPlay Shepard Melody/¡",PlayShepardMelody,0);
  719.     InstallMenuItem("\pPick Then Play Some Notes/2",PickThenPlaySomeNotes,0);
  720.     InstallMenuItem("\pPlay Some Bent Notes/3",PlaySomeBentNotes,0);
  721.     InstallMenuItem("\pBuild And Play Sequence/4",BuildSequenceAndPlay,0);
  722.     InstallMenuItem("\pBuild Music Movie/5",BuildMusicMovie,0);
  723.     InstallMenuItem("\pUse MIDI Input/6",UseMIDIInput,0);
  724. /*** Edit Menu ***/
  725.     InstallEditMenu(nil,nil,nil,nil,nil);
  726.  
  727.     OpenWindow(0,0,0);
  728.     }
  729.  
  730. void Hatstrap()
  731. /*
  732.   * clean up
  733.   */
  734.     {
  735.         ExitMovies();
  736.     }
  737.  
  738.